<?php

namespace app\common\library;


use app\admin\model\Setting;
use fast\Http;
use think\Env;
use think\Exception;

// 如果一次团的是多张，扫大众点评二维码得到的，其实就是第一张的团券code，其实扫码验券的接口没有什么用
// 验券接口还是一张一张的核销

// 在application/index/controller/Index.php文件里看到怎么得到
// auth_code 和 open_shop_uuid
// auth_code 每一年要更新一次

class Dianping
{
    protected $_appKey = '';
    protected $_appSecret = '';
    protected $_openShopUuid = '';
    protected $_authCode = '';


    public function __construct()
    {
        $this->_appKey = Env::get('dianping.app_key');
        $this->_appSecret = Env::get('dianping.app_secret');
        $this->_openShopUuid = Env::get('dianping.open_shop_uuid');
        $this->_authCode = Env::get('dianping.auth_code');
    }

    public function exchange($code, $count = 1)
    {
        $session = $this->getSession();
        if (false == $session) {
            throw new Exception('session没有获得');
        }

        $data = [
            'app_key' => $this->_appKey,
            'timestamp' => date('Y-m-d H:i:s'),
            'sign_method' => 'MD5',
            'format' => 'json',
            'v' => 1,
            'session' => $session,
        ];

        $arr = [
            'requestid'=>'123',
            'receipt_code' => $code,
            'count' => $count, //通过count的控制，可以一次性把多张的券的都兑换了
            'open_shop_uuid' => $this->_openShopUuid,
            'app_shop_account' =>'no_use',
            'app_shop_accountname' =>'no_use',
        ];

        $data['sign'] = $this->_calSign($data, $arr);//获取签名
        $data = array_merge($data, $arr);

        $headers = ['content-type:application/x-www-form-urlencoded'];
        $options = [
            CURLOPT_HTTPHEADER => $headers
        ];
        $url = 'https://openapi.dianping.com/router/tuangou/receipt/consume';//验券
        $result = Http::post($url, http_build_query($data), $options);
        $result = json_decode($result, true);

        return $result;
    }

    public function prepare($code)
    {

        $session = $this->getSession();
        if (false == $session) {
            throw new Exception('session没有获得');
        }

        $data = [
            'app_key' => $this->_appKey,
            'timestamp' => date('Y-m-d H:i:s'),
            'sign_method' => 'MD5',
            'format' => 'json',
            'v' => 1,
            'session' => $session,
        ];

        $arr = [
            'receipt_code' => $code,
            'open_shop_uuid' => $this->_openShopUuid,
        ];

        $data['sign'] = $this->_calSign($data, $arr);//获取签名

        $data = array_merge($data, $arr);

        $headers = ['content-type:application/x-www-form-urlencoded'];
        $options = [
            CURLOPT_HTTPHEADER => $headers
        ];
        $url = 'https://openapi.dianping.com/router/tuangou/receipt/prepare';// 查询
        $result = Http::post($url, http_build_query($data), $options);
        $result = json_decode($result, true);

        return $result;
    }

    protected function _calSign($data, $arr)
    {
        $data = array_merge($data, $arr);
        ksort($data);
        $src_value = "";
        foreach ($data as $key=>$value){
            $src_value.=($key.$value);
        }
        return md5($this->_appSecret.$src_value.$this->_appSecret);
    }

    protected function getSession()
    {
        $dianpingSession = Setting::where('name', 'dianping_session')->find();
        $dianpingExpiresIn = Setting::where('name', 'dianping_expires_in')->find();
        $dianpingRefreshCount = Setting::where('name', 'dianping_refresh_count')->find();
        $dianpingRefreshToken = Setting::where('name', 'dianping_refresh_token')->find();

        $headers = ['content-type:application/x-www-form-urlencoded'];
        $options = [
            CURLOPT_HTTPHEADER => $headers
        ];

        // 第一次得到session
        if (empty($dianpingSession->value) or $dianpingRefreshCount->value <= 2) {
            $url = 'https://openapi.dianping.com/router/oauth/token';
            $data = [
                'app_key' => $this->_appKey,
                'app_secret' => $this->_appSecret,
                'auth_code' => $this->_authCode,
                'grant_type' => 'authorization_code',
                'redirect_url' => Env::get('app.host') . '/index/index/meituanredirect',
            ];
            $result = Http::post($url, http_build_query($data), $options);
            $result = json_decode($result, true);
            if (200 == $result['code']) {
                $dianpingSession->value = $result['access_token'];
                $dianpingExpiresIn->value = $result['expires_in'];
                $dianpingRefreshCount->value = $result['remain_refresh_count'];
                $dianpingRefreshToken->value = $result['refresh_token'];

                $dianpingSession->save();
                $dianpingExpiresIn->save();
                $dianpingRefreshCount->save();
                $dianpingRefreshToken->save();

            } else {
                return false;
            }

        } else if ($dianpingSession->updatetime + $dianpingExpiresIn->value < time() + 3600 * 24 * 3) { //提前三天更新
            // 判断session的过期时间和更新次数
            $url = 'https://openapi.dianping.com/router/oauth/token';
            $data = [
                'app_key' => $this->_appKey,
                'app_secret' => $this->_appSecret,
                'grant_type' => 'refresh_token',
                'refresh_token' => $dianpingRefreshToken->value,
            ];
            $result = Http::post($url, http_build_query($data), $options);
            $result = json_decode($result, true);
            if (200 == $result['code']) {
                $dianpingSession->value = $result['access_token'];
                $dianpingExpiresIn->value = $result['expires_in'];
                $dianpingRefreshCount->value = $result['remain_refresh_count'];
                $dianpingRefreshToken->value = $result['refresh_token'];

                $dianpingSession->save();
                $dianpingExpiresIn->save();
                $dianpingRefreshCount->save();
                $dianpingRefreshToken->save();

            } else {
                return false;
            }

        }

        return $dianpingSession->value;
    }
}
